home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / mac / DirectX SDK / DXSDK / samples / Multimedia / DirectShow_WinXP / VMR / Renderless / AllocPresenter.cpp next >
C/C++ Source or Header  |  2001-10-08  |  13KB  |  465 lines

  1. //------------------------------------------------------------------------------
  2. // File: allocpresenter.cpp
  3. //
  4. // Desc: DirectShow sample code - Custom allocator-presenter
  5. //
  6. // Copyright (c) 2000-2001 Microsoft Corporation.  All rights reserved.
  7. //------------------------------------------------------------------------------
  8.  
  9. #include <streams.h>
  10. #include <mmreg.h>
  11. #include "project.h"
  12. #include <stdarg.h>
  13. #include <stdio.h>
  14. #include <math.h>
  15. #include <initguid.h>
  16.  
  17.  
  18. // {99d54f63-1a69-41ae-aa4d-c976eb3f0713}
  19. //DEFINE_GUID(CLSID_AllocPresenter, 0x99d54f63, 0x1a69, 0x41ae, 0xaa, 0x4d, 0xc9, 0x76, 0xeb, 0x3f, 0x07, 0x13);
  20.  
  21. template <typename T>
  22. __inline void INITDDSTRUCT(T& dd)
  23. {
  24.     ZeroMemory(&dd, sizeof(dd));
  25.     dd.dwSize = sizeof(dd);
  26. }
  27.  
  28.  
  29. /*****************************Private*Routine******************************\
  30. * CreateDefaultAllocatorPresenter
  31. *
  32. \**************************************************************************/
  33. HRESULT
  34. CMpegMovie::CreateDefaultAllocatorPresenter()
  35. {
  36.     HRESULT hr = S_OK;
  37.  
  38.     __try {
  39.         CHECK_HR(hr = CoCreateInstance(CLSID_AllocPresenter, NULL,
  40.                               CLSCTX_INPROC_SERVER,
  41.                               IID_IVMRSurfaceAllocator,
  42.                               (LPVOID*)&m_lpDefSA));
  43.  
  44.         CHECK_HR(hr = m_lpDefSA->QueryInterface(IID_IVMRImagePresenter,
  45.             (LPVOID*)&m_lpDefIP));
  46.  
  47.         CHECK_HR(hr = m_lpDefSA->QueryInterface(IID_IVMRWindowlessControl,
  48.             (LPVOID*)&m_lpDefWC));
  49.  
  50.         CHECK_HR(hr = m_lpDefWC->SetVideoClippingWindow(m_hwndApp));
  51.         CHECK_HR(hr = m_lpDefSA->AdviseNotify(this));
  52.         }
  53.     __finally {
  54.  
  55.         if(FAILED(hr)) {
  56.             RELEASE(m_lpDefWC);
  57.             RELEASE(m_lpDefIP);
  58.             RELEASE(m_lpDefSA);
  59.             }
  60.     }
  61.  
  62.     return hr;
  63. }
  64.  
  65.  
  66. /******************************Public*Routine******************************\
  67. * NonDelegatingQueryInterface
  68. *
  69. \**************************************************************************/
  70. STDMETHODIMP
  71. CMpegMovie::NonDelegatingQueryInterface(
  72.     REFIID riid,
  73.     void** ppv
  74.     )
  75. {
  76.     if(riid == IID_IVMRSurfaceAllocator)
  77.     {
  78.         return GetInterface((IVMRSurfaceAllocator*)this, ppv);
  79.     }
  80.     else if(riid == IID_IVMRImagePresenter)
  81.     {
  82.         return GetInterface((IVMRImagePresenter*)this, ppv);
  83.     }
  84.  
  85.     return CUnknown::NonDelegatingQueryInterface(riid,ppv);
  86. }
  87.  
  88.  
  89. //////////////////////////////////////////////////////////////////////////////
  90. //
  91. // IVMRSurfaceAllocator
  92. //
  93. //////////////////////////////////////////////////////////////////////////////
  94.  
  95. /******************************Public*Routine******************************\
  96. * AllocateSurfaces
  97. *
  98. \**************************************************************************/
  99. STDMETHODIMP
  100. CMpegMovie::AllocateSurface(
  101.     DWORD_PTR dwUserID,
  102.     VMRALLOCATIONINFO* lpAllocInfo,
  103.     DWORD* lpdwBuffer,
  104.     LPDIRECTDRAWSURFACE7* lplpSurface
  105.     )
  106. {
  107.     return m_lpDefSA->AllocateSurface(dwUserID, lpAllocInfo,
  108.         lpdwBuffer, lplpSurface);
  109. }
  110.  
  111.  
  112. /******************************Public*Routine******************************\
  113. * FreeSurfaces()
  114. *
  115. \**************************************************************************/
  116. STDMETHODIMP
  117. CMpegMovie::FreeSurface(
  118.     DWORD_PTR dwUserID
  119.     )
  120. {
  121.     return m_lpDefSA->FreeSurface(dwUserID);
  122. }
  123.  
  124.  
  125. /******************************Public*Routine******************************\
  126. * PrepareSurface
  127. *
  128. \**************************************************************************/
  129. STDMETHODIMP
  130. CMpegMovie::PrepareSurface(
  131.     DWORD_PTR dwUserID,
  132.     LPDIRECTDRAWSURFACE7 lplpSurface,
  133.     DWORD dwSurfaceFlags
  134.     )
  135. {
  136.     return m_lpDefSA->PrepareSurface(dwUserID, lplpSurface, dwSurfaceFlags);
  137. }
  138.  
  139.  
  140. /******************************Public*Routine******************************\
  141. * AdviseNotify
  142. *
  143. \**************************************************************************/
  144. STDMETHODIMP
  145. CMpegMovie::AdviseNotify(
  146.     IVMRSurfaceAllocatorNotify* lpIVMRSurfAllocNotify
  147.     )
  148. {
  149.     return m_lpDefSA->AdviseNotify(lpIVMRSurfAllocNotify);
  150. }
  151.  
  152.  
  153. //////////////////////////////////////////////////////////////////////////////
  154. //
  155. // IVMRSurfaceAllocatorNotify
  156. //
  157. //////////////////////////////////////////////////////////////////////////////
  158.  
  159. /******************************Public*Routine******************************\
  160. * AdviseSurfaceAllocator
  161. *
  162. \**************************************************************************/
  163. STDMETHODIMP
  164. CMpegMovie::AdviseSurfaceAllocator(
  165.     DWORD_PTR dwUserID,
  166.     IVMRSurfaceAllocator* lpIVRMSurfaceAllocator
  167.     )
  168. {
  169.     return m_lpDefSAN->AdviseSurfaceAllocator(dwUserID, lpIVRMSurfaceAllocator);
  170. }
  171.  
  172.  
  173. /******************************Public*Routine******************************\
  174. * SetDDrawDevice
  175. *
  176. \**************************************************************************/
  177. STDMETHODIMP
  178. CMpegMovie::SetDDrawDevice(LPDIRECTDRAW7 lpDDrawDevice,HMONITOR hMonitor)
  179. {
  180.     return m_lpDefSAN->SetDDrawDevice(lpDDrawDevice, hMonitor);
  181. }
  182.  
  183.  
  184. /******************************Public*Routine******************************\
  185. * ChangeDDrawDevice
  186. *
  187. \**************************************************************************/
  188. STDMETHODIMP
  189. CMpegMovie::ChangeDDrawDevice(LPDIRECTDRAW7 lpDDrawDevice,HMONITOR hMonitor)
  190. {
  191.     return m_lpDefSAN->ChangeDDrawDevice(lpDDrawDevice, hMonitor);
  192. }
  193.  
  194.  
  195. /*****************************Private*Routine******************************\
  196. * DDSurfEnumFunc
  197. *
  198. \**************************************************************************/
  199. HRESULT WINAPI
  200. DDSurfEnumFunc(
  201.     LPDIRECTDRAWSURFACE7 pdds,
  202.     DDSURFACEDESC2* pddsd,
  203.     void* lpContext
  204.     )
  205. {
  206.     LPDIRECTDRAWSURFACE7* ppdds = (LPDIRECTDRAWSURFACE7*)lpContext;
  207.  
  208.     DDSURFACEDESC2 ddsd;
  209.     INITDDSTRUCT(ddsd);
  210.  
  211.     HRESULT hr = pdds->GetSurfaceDesc(&ddsd);
  212.     if(SUCCEEDED(hr))
  213.     {
  214.         if(ddsd.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
  215.         {
  216.             *ppdds = pdds;
  217.             return DDENUMRET_CANCEL;
  218.  
  219.         }
  220.     }
  221.  
  222.     pdds->Release();
  223.     return DDENUMRET_OK;
  224. }
  225.  
  226.  
  227. /*****************************Private*Routine******************************\
  228. * OnSetDDrawDevice
  229. *
  230. \**************************************************************************/
  231. HRESULT
  232. CMpegMovie::OnSetDDrawDevice(
  233.     LPDIRECTDRAW7 pDD,
  234.     HMONITOR hMon
  235.     )
  236. {
  237.     HRESULT hr = S_OK;
  238.  
  239.     RELEASE(m_pddsRenderT);
  240.     RELEASE(m_pddsPriText);
  241.     RELEASE(m_pddsPrimary);
  242.  
  243.     __try
  244.     {
  245.  
  246.         DDSURFACEDESC2 ddsd;  // A surface description structure
  247.         INITDDSTRUCT(ddsd);
  248.         ddsd.dwFlags = DDSD_CAPS;
  249.         ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
  250.  
  251.         CHECK_HR(hr = pDD->EnumSurfaces(DDENUMSURFACES_DOESEXIST |
  252.             DDENUMSURFACES_ALL,
  253.             &ddsd,
  254.             &m_pddsPrimary,
  255.             DDSurfEnumFunc));
  256.         if(!m_pddsPrimary)
  257.         {
  258.             hr = E_FAIL;
  259.             __leave;
  260.         }
  261.  
  262.         MONITORINFOEX miInfoEx;
  263.         miInfoEx.cbSize = sizeof(miInfoEx);
  264.         GetMonitorInfo(hMon, &miInfoEx);
  265.  
  266.         INITDDSTRUCT(ddsd);
  267.         ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
  268.         ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
  269.         ddsd.dwWidth = (miInfoEx.rcMonitor.right - miInfoEx.rcMonitor.left);
  270.         ddsd.dwHeight = (miInfoEx.rcMonitor.bottom - miInfoEx.rcMonitor.top);
  271.  
  272.         CHECK_HR(hr = pDD->CreateSurface(&ddsd, &m_pddsPriText, NULL));
  273.         CHECK_HR(hr = pDD->CreateSurface(&ddsd, &m_pddsRenderT, NULL));
  274.  
  275.     }
  276.     __finally
  277.     {
  278.         if(FAILED(hr))
  279.         {
  280.             RELEASE(m_pddsRenderT);
  281.             RELEASE(m_pddsPriText);
  282.             RELEASE(m_pddsPrimary);
  283.         }
  284.     }
  285.  
  286.     return hr;
  287. }
  288.  
  289.  
  290. /******************************Public*Routine******************************\
  291. * RestoreDDrawSurfaces
  292. *
  293. \**************************************************************************/
  294. STDMETHODIMP CMpegMovie::RestoreDDrawSurfaces()
  295. {
  296.     return m_lpDefSAN->RestoreDDrawSurfaces();
  297. }
  298.  
  299.  
  300. /******************************Public*Routine******************************\
  301. * RestoreDDrawSurfaces
  302. *
  303. \**************************************************************************/
  304. STDMETHODIMP
  305. CMpegMovie::NotifyEvent(LONG EventCode, LONG_PTR lp1, LONG_PTR lp2)
  306. {
  307.     return m_lpDefSAN->NotifyEvent(EventCode, lp1, lp2);
  308. }
  309.  
  310.  
  311. /******************************Public*Routine******************************\
  312. * SetBorderColor
  313. *
  314. \**************************************************************************/
  315. STDMETHODIMP
  316. CMpegMovie::SetBorderColor(
  317.     COLORREF clr
  318.     )
  319. {
  320.     return m_lpDefSAN->SetBorderColor(clr);
  321. }
  322.  
  323.  
  324. //////////////////////////////////////////////////////////////////////////////
  325. //
  326. // IVMRImagePresenter
  327. //
  328. //////////////////////////////////////////////////////////////////////////////
  329.  
  330. /******************************Public*Routine******************************\
  331. * StartPresenting()
  332. *
  333. \**************************************************************************/
  334. STDMETHODIMP
  335. CMpegMovie::StartPresenting(DWORD_PTR dwUserID)
  336. {
  337.     return m_lpDefIP->StartPresenting(dwUserID);
  338. }
  339.  
  340.  
  341. /******************************Public*Routine******************************\
  342. * StopPresenting()
  343. *
  344. \**************************************************************************/
  345. STDMETHODIMP
  346. CMpegMovie::StopPresenting(DWORD_PTR dwUserID)
  347. {
  348.     return m_lpDefIP->StopPresenting(dwUserID);
  349. }
  350.  
  351.  
  352. /******************************Public*Routine******************************\
  353. * PresentImage
  354. *
  355. \**************************************************************************/
  356. STDMETHODIMP
  357. CMpegMovie::PresentImage(
  358.     DWORD_PTR dwUserID,
  359.     VMRPRESENTATIONINFO* lpPresInfo
  360.     )
  361. {
  362. #if 0
  363.     LPDIRECTDRAWSURFACE7 lpSurface = lpPresInfo->lpSurf;
  364.     const REFERENCE_TIME rtNow = lpPresInfo->rtStart;
  365.     const DWORD dwSurfaceFlags = lpPresInfo->dwFlags;
  366.  
  367.     if(m_iDuration > 0)
  368.     {
  369.         HRESULT hr;
  370.         RECT rs, rd;
  371.         DDSURFACEDESC2 ddsdV;
  372.  
  373.         INITDDSTRUCT(ddsdV);
  374.         hr = lpSurface->GetSurfaceDesc(&ddsdV);
  375.  
  376.         DDSURFACEDESC2 ddsdP;
  377.         INITDDSTRUCT(ddsdP);
  378.         hr = m_pddsPriText->GetSurfaceDesc(&ddsdP);
  379.  
  380.         FLOAT fPos = (FLOAT)m_iDuration / 30.0F;
  381.         FLOAT fPosInv = 1.0F - fPos;
  382.  
  383.         SetRect(&rs, 0, 0,
  384.             MulDiv((int)ddsdV.dwWidth, 30 - m_iDuration, 30),
  385.             ddsdV.dwHeight);
  386.  
  387.         SetRect(&rd, 0, 0,
  388.             MulDiv((int)ddsdP.dwWidth, 30 - m_iDuration, 30),
  389.             ddsdP.dwHeight);
  390.  
  391.         hr = m_pddsRenderT->Blt(&rd, lpSurface,
  392.             &rs, DDBLT_WAIT, NULL);
  393.  
  394.         SetRect(&rs, 0, 0,
  395.             MulDiv((int)ddsdP.dwWidth, m_iDuration, 30),
  396.             ddsdP.dwHeight);
  397.  
  398.         SetRect(&rd,
  399.             (int)ddsdP.dwWidth - MulDiv((int)ddsdP.dwWidth, m_iDuration, 30),
  400.             0,
  401.             ddsdP.dwWidth,
  402.             ddsdP.dwHeight);
  403.  
  404.         hr = m_pddsRenderT->Blt(&rd, m_pddsPriText,
  405.             &rs, DDBLT_WAIT, NULL);
  406.  
  407.         //
  408.         // need to wait for VBlank before blt-ing
  409.         //
  410.         {
  411.             LPDIRECTDRAW lpdd;
  412.             hr = m_pddsPrimary->GetDDInterface((LPVOID*)&lpdd);
  413.             if(SUCCEEDED(hr))
  414.             {
  415.                 DWORD dwScanLine;
  416.                 for(; ;)
  417.                 {
  418.                     hr = lpdd->GetScanLine(&dwScanLine);
  419.  
  420.                     if(hr ==  DDERR_VERTICALBLANKINPROGRESS)
  421.                     {
  422.                         break;
  423.                     }
  424.  
  425.                     if(FAILED(hr))
  426.                     {
  427.                         break;
  428.                     }
  429.  
  430.                     if((LONG)dwScanLine>= rd.top)
  431.                     {
  432.                         if((LONG)dwScanLine <= rd.bottom)
  433.                         {
  434.                             continue;
  435.                         }
  436.                     }
  437.  
  438.                     break;
  439.                 }
  440.  
  441.                 RELEASE(lpdd);
  442.             }
  443.         }
  444.  
  445.         hr = m_pddsPrimary->Blt(NULL, m_pddsRenderT,
  446.             NULL, DDBLT_WAIT, NULL);
  447.  
  448.         m_iDuration--;
  449.         if(m_iDuration == 0 && (ddsdV.ddsCaps.dwCaps & DDSCAPS_OVERLAY))
  450.         {
  451.             // need to get the color key visible again.
  452.             InvalidateRect(m_hwndApp, NULL, FALSE);
  453.         }
  454.         return hr;
  455.     }
  456.     else
  457.     {
  458.         return m_lpDefIP->PresentImage(dwUserID, lpPresInfo);
  459.     }
  460. #endif
  461.  
  462.     return m_lpDefIP->PresentImage(dwUserID, lpPresInfo);
  463. }
  464.  
  465.